package com.xyoto.takeawayBusiness.service.impl;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xyoto.takeawayBusiness.constant.DataBasesOperationResult;
import com.xyoto.takeawayBusiness.constant.FileModelConstant;
import com.xyoto.takeawayBusiness.dto.SaveShoppingDto;
import com.xyoto.takeawayBusiness.dto.ShoppingPropDto;
import com.xyoto.takeawayBusiness.dto.ShoppingSpecDto;
import com.xyoto.takeawayBusiness.dto.UpdateShoppingDto;
import com.xyoto.takeawayBusiness.entity.Shopping;
import com.xyoto.takeawayBusiness.entity.ShoppingAttribute;
import com.xyoto.takeawayBusiness.entity.ShoppingGoods;
import com.xyoto.takeawayBusiness.enums.CommonEnum;
import com.xyoto.takeawayBusiness.enums.ShoppingEnum;
import com.xyoto.takeawayBusiness.enums.ShoppingTypeEnum;
import com.xyoto.takeawayBusiness.exception.ExceptionUtils;
import com.xyoto.takeawayBusiness.mapper.ShoppingAttributeMapper;
import com.xyoto.takeawayBusiness.mapper.ShoppingGoodsMapper;
import com.xyoto.takeawayBusiness.mapper.ShoppingMapper;
import com.xyoto.takeawayBusiness.mapper.ShoppingTypeMapper;
import com.xyoto.takeawayBusiness.service.ShoppingService;
import com.xyoto.takeawayBusiness.utils.JudgeParamUtils;
import com.xyoto.takeawayBusiness.utils.MinioUtils;
import com.xyoto.takeawayBusiness.utils.Result;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.web3j.abi.datatypes.Int;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;

/**
 * @ClassName: 定义菜单Service实现类
 * @Author: 挽风
 * @Date: 2022
 * @Copyright: 2022 by 挽风
 * @Description:
 **/
@Service
@Slf4j
public class ShoppingServiceImpl implements ShoppingService {

    @Autowired
    private ShoppingTypeMapper shoppingTypeMapper;

    @Autowired
    private MinioUtils minioUtils;

    @Autowired
    private ShoppingMapper shoppingMapper;

    @Autowired
    private ShoppingGoodsMapper shoppingGoodsMapper;

    @Autowired
    private ShoppingAttributeMapper shoppingAttributeMapper;

    /**
     * 修改商品信息
     * @param updateDto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result updateShopping(UpdateShoppingDto updateDto) {
        JudgeParamUtils.judgeIntegerParam(updateDto.getShoppingId(), ShoppingEnum.SHOPPING_ERROR);

        // 查询商品信息
        Shopping shopping = shoppingMapper.getShoppingInfo(updateDto.getShoppingId());
        if (shopping == null){
            ExceptionUtils.error(ShoppingEnum.UPDATE_SHOPPING_FAIL);
        }
        if (updateDto.getPath() != null){
            try {
                String path = minioUtils.uploadFile(updateDto.getPath(), FileModelConstant.SHOPPING_MODEL);
                if (StrUtil.isEmpty(path)){
                    ExceptionUtils.error(ShoppingEnum.SHOPPING_IMG_UPDATE_FAIL);
                }
                shopping.setPath(path);
            } catch (Exception e) {
                ExceptionUtils.error(ShoppingEnum.SHOPPING_IMG_UPDATE_FAIL);
                log.info("——商品图片上传失败——");
            }
        }
        if (updateDto.getShoppingTypeId() != null){
            JudgeParamUtils.judgeIntegerParam(updateDto.getShoppingTypeId());
            // 查询商品类别是否存在
            Integer flag = shoppingTypeMapper.isExistShoppingType(updateDto.getShoppingTypeId());
            if (flag != DataBasesOperationResult.SUCCESS){
                ExceptionUtils.error(ShoppingTypeEnum.SHOPPING_TYPE_NO_EXIST);
            }
            shopping.setShoppingTypeId(updateDto.getShoppingTypeId());
        }
        if (updateDto.getPrice() != null){
            JudgeParamUtils.judgeIntegerParam(updateDto.getPrice());
            shopping.setPrice(updateDto.getPrice());
        }
        if (updateDto.getBoxPrice() != null){
            if (updateDto.getBoxPrice() <= 0){
                shopping.setBoxPrice(0);
            }else{
                shopping.setBoxPrice(updateDto.getBoxPrice());
            }
        }
        if (StrUtil.isNotBlank(updateDto.getContent())){
            shopping.setContent(updateDto.getContent());
        }
        if (StrUtil.isNotBlank(updateDto.getShoppingName())){
            shopping.setShoppingName(updateDto.getShoppingName());
        }

        // 修改商品规格
        if (!StrUtil.isEmpty(updateDto.getSpecList())){
            String str = updateDto.getSpecList();
            List<ShoppingSpecDto> list = JSONObject.parseArray(str, ShoppingSpecDto.class);
            updateProdSpec(updateDto.getShoppingId(), list);
        }

        // 修改商品属性
        if (!StrUtil.isEmpty(updateDto.getPropList())){
            String stf = updateDto.getPropList();
            List<ShoppingPropDto> list = JSON.parseArray(stf, ShoppingPropDto.class);
            updateProdProd(updateDto.getShoppingId(), list);
        }

        // 修改商品
        Integer flag = shoppingMapper.updateShopping(shopping);
        if (flag == DataBasesOperationResult.ERROR){
            ExceptionUtils.error(ShoppingEnum.UPDATE_SHOPPING_FAIL);
        }
        return Result.success();
    }

    /**
     * 修改商品规格
     * @param prodId
     */
    private void updateProdSpec(Integer prodId, List<ShoppingSpecDto> specDtoList){
        List<ShoppingGoods> shoppingGoodsList = new ArrayList<>();

        specDtoList.stream().map(item -> {
            if (item != null){
                ShoppingGoods shoppingGoods = new ShoppingGoods();
                if (item.getId() != null){
                    shoppingGoods.setId(item.getId());
                }
                shoppingGoods.setShoppingId(prodId);
                shoppingGoods.setGoodsName(item.getSpecName());
                shoppingGoods.setPrice(item.getPrice());
                shoppingGoods.setModifiedTime(new Date());
                shoppingGoods.setCreateTime(new Date());
                shoppingGoodsList.add(shoppingGoods);
            }
            return shoppingGoodsList;
        }).collect(Collectors.toList());

        for (ShoppingGoods shoppingGoods : shoppingGoodsList){
            if (shoppingGoods.getId() != null){
                // 更新
                Integer flag = shoppingGoodsMapper.updateGoods(shoppingGoods);
                if (flag == DataBasesOperationResult.ERROR){
                    ExceptionUtils.error(ShoppingEnum.UPDATE_GOODS_FAIL);
                }
            }else{
                // 新增
                Integer flag = shoppingGoodsMapper.addProdGoods(shoppingGoods);
                if (flag == null || flag == DataBasesOperationResult.ERROR){
                    ExceptionUtils.error(ShoppingEnum.SAVE_SHOPPING_GOODS_FAIL);
                }
            }

        }
    }

    /**
     * 修改商品属性
     * @param prodId
     * @param propDtoList
     */
    private void updateProdProd(Integer prodId, List<ShoppingPropDto> propDtoList){
        List<ShoppingAttribute> shoppingAttributeList = new ArrayList<>();

        propDtoList.stream().map(item -> {
            ShoppingAttribute shoppingAttribute = new ShoppingAttribute();
            if(item != null){
                if (item.getId() != null){
                    shoppingAttribute.setId(item.getId());
                }
                shoppingAttribute.setShoppingId(prodId);
                shoppingAttribute.setAttributeName(item.getProdName());
                shoppingAttribute.setAttributeLable(item.getPropValue());
                shoppingAttribute.setModifiedTime(new Date());
                shoppingAttribute.setCreateTime(new Date());
                shoppingAttributeList.add(shoppingAttribute);
            }
            return shoppingAttributeList;
        }).collect(Collectors.toList());
        for (ShoppingAttribute shoppingAttribute : shoppingAttributeList){
            if (shoppingAttribute.getId() != null){
                // 修改
                Integer flag = shoppingAttributeMapper.updateShoppingAttribute(shoppingAttribute);
                if (flag == null || flag == DataBasesOperationResult.ERROR){
                    ExceptionUtils.error(ShoppingEnum.UPDATE_ATTRIBUTE_FAIL);
                }
            }else{
                Integer flag = shoppingAttributeMapper.addProdAttribute(shoppingAttribute);
                if (flag == null || flag == DataBasesOperationResult.ERROR){
                    ExceptionUtils.error(ShoppingEnum.SAVE_SHOPPING_ATTRIBUTE_FAIL);
                }
            }
        }
    }

    /**
     * 新增商品信息
     * @param saveDto
     * @return
     */
    @Override
    @Transactional
    public Result addShopping(SaveShoppingDto saveDto) {
        // 参数校验
        JudgeParamUtils.judgeIntegerParam(saveDto.getShopId(), ShoppingEnum.SHOP_ERROR);
        JudgeParamUtils.judgeIntegerParam(saveDto.getShoppingTypeId(), ShoppingTypeEnum.SHOPPING_TYPE_ERROR);
        if (saveDto.getPath() == null || saveDto.getPath().getSize() == 0){
            ExceptionUtils.error(ShoppingEnum.SHOPPING_IMG_IS_NULL);
        }

        // 查询商品类别
        Integer isExist = shoppingTypeMapper.isExistShoppingType(saveDto.getShoppingTypeId());
        if (isExist != DataBasesOperationResult.SUCCESS){
            ExceptionUtils.error(ShoppingTypeEnum.SHOPPING_TYPE_NO_EXIST);
        }

        // 上传文件
        String path = null;
        try {
            path = minioUtils.uploadFile(saveDto.getPath(), FileModelConstant.SHOPPING_MODEL);
            if (StrUtil.isEmpty(path)){
                ExceptionUtils.error(ShoppingEnum.SHOPPING_IMG_UPDATE_FAIL);
            }
        } catch (Exception e) {
            log.info("——文件上传失败——");
            e.printStackTrace();
            ExceptionUtils.error(ShoppingEnum.SHOPPING_IMG_UPDATE_FAIL);
        }

        // 存储商品信息
        Shopping shopping = new Shopping();
        BeanUtils.copyProperties(saveDto, shopping);
        shopping.setPath(path);
        shopping.setShoppingSales(0);
        shopping.setCreateTime(new Date());
        // 生成唯一标识用于查询主键
        String uuid = UUID.randomUUID().toString().replace("-", "");
        shopping.setMark(uuid);
        Integer flag = shoppingMapper.saveShopping(shopping);

        if (flag == DataBasesOperationResult.ERROR){
            log.info("商品存储失败");
            ExceptionUtils.error(ShoppingEnum.SHOPPING_SAVE_FAIL);
        }

        // 查询主键
        Integer prodId = shoppingMapper.getShoppingId(uuid);

        // 存储规格
        if (!StrUtil.isEmpty(saveDto.getSpecList())){
            // 解析属性结合
            String str = saveDto.getSpecList();
            List<ShoppingSpecDto> list = JSONObject.parseArray(str, ShoppingSpecDto.class);
            saveProdSpec(prodId, list);
        }

        // 存储属性
        if (!StrUtil.isEmpty(saveDto.getPropList())){
            String stf = saveDto.getPropList();
            List<ShoppingPropDto> list = JSON.parseArray(stf, ShoppingPropDto.class);
            saveProdProd(prodId, list);
        }
        return Result.success();
    }

    /**
     * 存储商品规格
     * @param prodId
     */
    private void saveProdSpec(Integer prodId, List<ShoppingSpecDto> specDtoList){
        List<ShoppingGoods> shoppingGoodsList = new ArrayList<>();

        specDtoList.stream().map(item -> {
            if (item != null){
                ShoppingGoods shoppingGoods = new ShoppingGoods();
                shoppingGoods.setShoppingId(prodId);
                shoppingGoods.setGoodsName(item.getSpecName());
                shoppingGoods.setPrice(item.getPrice());
                shoppingGoods.setCreateTime(new Date());
                shoppingGoodsList.add(shoppingGoods);
            }
            return shoppingGoodsList;
        }).collect(Collectors.toList());

        for (ShoppingGoods shoppingGoods : shoppingGoodsList){
            Integer flag = shoppingGoodsMapper.saveGoods(shoppingGoods);
            if (flag == DataBasesOperationResult.ERROR){
                ExceptionUtils.error(ShoppingEnum.SAVE_SHOPPING_GOODS_FAIL);
            }
        }
    }

    /**
     * 存储商品属性
     * @param prodId
     * @param propDtoList
     */
    private void saveProdProd(Integer prodId, List<ShoppingPropDto> propDtoList){
        List<ShoppingAttribute> shoppingAttributeList = new ArrayList<>();

        propDtoList.stream().map(item -> {
            if(item != null){
                ShoppingAttribute shoppingAttribute = new ShoppingAttribute();
                shoppingAttribute.setShoppingId(prodId);
                shoppingAttribute.setAttributeName(item.getProdName());
                shoppingAttribute.setAttributeLable(item.getPropValue());
                shoppingAttribute.setCreateTime(new Date());
                shoppingAttributeList.add(shoppingAttribute);
            }
            return shoppingAttributeList;
        }).collect(Collectors.toList());
        for (ShoppingAttribute shoppingAttribute : shoppingAttributeList){
            Integer flag = shoppingAttributeMapper.saveShoppingAttribute(shoppingAttribute);
            if (flag == null || flag == DataBasesOperationResult.ERROR){
                ExceptionUtils.error(ShoppingEnum.SAVE_SHOPPING_ATTRIBUTE_FAIL);
            }
        }
    }

}
